﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using AChance.Bll.Func;
using AChance.Dal.Entity;
using AChance.Dal.Func;
using AChance.Func;

namespace AChance.Bll.Trans
{
    public partial class TrnSql
    {
        /// <summary>
        /// 更新数据库结构
        /// </summary>
        [BllTrans(LockMode = FunLock.Mode.Distributed)]
        public partial class ChgStruct
        {
            public static void Exec()
            {
                #region 操作执行
                FDWUPD uPD = DalOper.Sql.Select<FDWUPD>(DalConst.SqlVer.DATA_STRUCT, null);
                if (uPD is null)
                {
                    uPD = new FDWUPD()
                    {
                        UPDNAME = DalConst.SqlVer.DATA_STRUCT,
                        UPDVERSION = DalConst.SqlVer.DATA_STRUCT_VER
                    };
                    DalOper.Sql.Insert(uPD);
                    return;
                }
                //任何旧版本 --> 最新版本
                if (uPD.UPDVERSION < DalConst.SqlVer.DATA_STRUCT_VER)
                {
                    var sql = new StringBuilder();

                    #region 版本1
                    if (uPD.UPDVERSION < 1)
                    {
                        //sql.Clear();

                    }
                    #endregion

                    #region 版本2
                    if (uPD.UPDVERSION < 2)
                    {
                        //sql.Clear();

                    }
                    #endregion

                    uPD.UPDVERSION = DalConst.SqlVer.DATA_STRUCT_VER;
                    DalOper.Sql.Update(uPD);
                }
                else if (uPD.UPDVERSION > DalConst.SqlVer.DATA_STRUCT_VER)
                {
                    throw new Exception("程序中的数据库结构版本(" + DalConst.SqlVer.DATA_STRUCT_VER + ")低于当前数据库中的版本(" + uPD.UPDVERSION + ")");
                }
                #endregion
            }
        }
        /// <summary>
        /// 更新数据库索引
        /// </summary>
        [BllTrans(LockMode = FunLock.Mode.Distributed)]
        public partial class ChgIndex
        {
            public static void Exec()
            {
                #region 操作执行
                FDWUPD uPD = DalOper.Sql.Select<FDWUPD>(DalConst.SqlVer.DATA_INDEX, null);
                if (uPD is null)
                {
                    uPD = new FDWUPD()
                    {
                        UPDNAME = DalConst.SqlVer.DATA_INDEX,
                        UPDVERSION = 0
                    };
                    DalOper.Sql.Insert(uPD);
                }
                //任何旧版本 --> 最新版本
                if (uPD.UPDVERSION < DalConst.SqlVer.DATA_INDEX_VER)
                {
                    var sql = new StringBuilder();

                    #region 版本1
                    if (uPD.UPDVERSION < 1)
                    {
                        //sql.Clear();

                    }
                    #endregion

                    #region 版本2
                    if (uPD.UPDVERSION < 2)
                    {
                        //sql.Clear();

                    }
                    #endregion

                    uPD.UPDVERSION = DalConst.SqlVer.DATA_INDEX_VER;
                    DalOper.Sql.Update(uPD);
                }
                else if (uPD.UPDVERSION > DalConst.SqlVer.DATA_INDEX_VER)
                {
                    throw new Exception("程序中的数据库索引版本(" + DalConst.SqlVer.DATA_INDEX_VER + ")低于当前数据库中的版本(" + uPD.UPDVERSION + ")");
                }
                #endregion
            }
        }
        /// <summary>
        /// 更新数据库视图
        /// </summary>
        [BllTrans(LockMode = FunLock.Mode.Distributed)]
        public partial class ChgView
        {
            public static void Exec()
            {
                #region 操作执行
                FDWUPD uPD = DalOper.Sql.Select<FDWUPD>(DalConst.SqlVer.DATA_VIEW, null);
                if (uPD is null)
                {
                    uPD = new FDWUPD()
                    {
                        UPDNAME = DalConst.SqlVer.DATA_VIEW,
                        UPDVERSION = 0
                    };
                    DalOper.Sql.Insert(uPD);
                }
                //任何旧版本 --> 最新版本
                if (uPD.UPDVERSION < DalConst.SqlVer.DATA_VIEW_VER)
                {
                    var sql = new StringBuilder();



                    uPD.UPDVERSION = DalConst.SqlVer.DATA_VIEW_VER;
                    DalOper.Sql.Update(uPD);
                }
                else if (uPD.UPDVERSION > DalConst.SqlVer.DATA_VIEW_VER)
                {
                    throw new Exception("程序中的数据库视图版本(" + DalConst.SqlVer.DATA_VIEW_VER + ")低于当前数据库中的版本(" + uPD.UPDVERSION + ")");
                }
                #endregion
            }
        }
        /// <summary>
        /// 更新数据库存储过程
        /// </summary>
        [BllTrans(LockMode = FunLock.Mode.Distributed)]
        public partial class ChgProc
        {
            public static void Exec()
            {
                #region 操作执行
                FDWUPD uPD = DalOper.Sql.Select<FDWUPD>(DalConst.SqlVer.DATA_PROC, null);
                if (uPD is null)
                {
                    uPD = new FDWUPD()
                    {
                        UPDNAME = DalConst.SqlVer.DATA_PROC,
                        UPDVERSION = 0
                    };
                    DalOper.Sql.Insert(uPD);
                }
                //任何旧版本 --> 最新版本
                if (uPD.UPDVERSION < DalConst.SqlVer.DATA_PROC_VER)
                {
                    var sql = new StringBuilder();

                    #region PTYPUB
                    #region PTYPUB_PROCEDURE1(记录数据表数据更新时间)
                    sql.Clear();
                    sql.Append(" DROP PROCEDURE IF EXISTS PTYPUB_PROCEDURE1; ");
                    DalOper.Sql.ExecDDL(sql.ToString());
                    sql.Clear();
                    sql.Append(" CREATE PROCEDURE PTYPUB_PROCEDURE1 ");
                    sql.Append(" (TABLENAME VARCHAR(32)) ");
                    sql.Append(" BEGIN ");
                    sql.Append(" DECLARE UPDATEDATE VARCHAR(8); ");
                    sql.Append(" DECLARE UPDATETIME VARCHAR(6); ");
                    sql.Append(" SET UPDATEDATE = DATE_FORMAT(NOW(), '%Y%m%d'); ");
                    sql.Append(" SET UPDATETIME = DATE_FORMAT(NOW(), '%H%i%S'); ");
                    sql.Append(" DELETE FROM PTYUDT WHERE UDTTABLENAME = TABLENAME; ");
                    sql.Append(" INSERT INTO PTYUDT(UDTTABLENAME, UDTUPDATEDATE, UDTUPDATETIME) VALUES (TABLENAME, UPDATEDATE, UPDATETIME); ");
                    sql.Append(" END; ");
                    DalOper.Sql.ExecDDL(sql.ToString());
                    #endregion
                    #endregion

                    uPD.UPDVERSION = DalConst.SqlVer.DATA_PROC_VER;
                    DalOper.Sql.Update(uPD);
                }
                else if (uPD.UPDVERSION > DalConst.SqlVer.DATA_PROC_VER)
                {
                    throw new Exception("程序中的数据库存储过程版本(" + DalConst.SqlVer.DATA_PROC_VER + ")低于当前数据库中的版本(" + uPD.UPDVERSION + ")");
                }
                #endregion
            }
        }
        /// <summary>
        /// 更新数据库触发器
        /// </summary>
        [BllTrans(LockMode = FunLock.Mode.Distributed)]
        public partial class ChgTrigger
        {
            public static void Exec()
            {
                #region 操作执行
                FDWUPD uPD = DalOper.Sql.Select<FDWUPD>(DalConst.SqlVer.DATA_TRIGGER, null);
                if (uPD is null)
                {
                    uPD = new FDWUPD()
                    {
                        UPDNAME = DalConst.SqlVer.DATA_TRIGGER,
                        UPDVERSION = 0
                    };
                    DalOper.Sql.Insert(uPD);
                }
                //任何旧版本 --> 最新版本
                if (uPD.UPDVERSION < DalConst.SqlVer.DATA_TRIGGER_VER)
                {
                    var sql = new StringBuilder();

                    #region PTYPUB
                    #region 记录数据表数据更新时间
                    foreach (string tableName in BllCache.Base.Infos.Keys)
                    {
                        #region PTYPUB_TRIGGER1
                        sql.Clear();
                        sql.AppendLine(" DROP TRIGGER IF EXISTS " + tableName + "_PTYPUB_TRIGGER1; ");
                        DalOper.Sql.ExecDDL(sql.ToString());
                        sql.Clear();
                        sql.Append(" CREATE TRIGGER " + tableName + "_PTYPUB_TRIGGER1 ");
                        sql.Append(" AFTER INSERT ON " + tableName + " ");
                        sql.Append(" FOR EACH ROW ");
                        sql.Append(" BEGIN ");
                        sql.Append(" CALL PTYPUB_PROCEDURE1('" + tableName + "'); ");
                        sql.Append(" END; ");
                        DalOper.Sql.ExecDDL(sql.ToString());
                        #endregion

                        #region PTYPUB_TRIGGER2
                        sql.Clear();
                        sql.Append(" DROP TRIGGER IF EXISTS " + tableName + "_PTYPUB_TRIGGER2; ");
                        DalOper.Sql.ExecDDL(sql.ToString());
                        sql.Clear();
                        sql.Append(" CREATE TRIGGER " + tableName + "_PTYPUB_TRIGGER2 ");
                        sql.Append(" AFTER UPDATE ON " + tableName + " ");
                        sql.Append(" FOR EACH ROW ");
                        sql.Append(" BEGIN ");
                        sql.Append(" CALL PTYPUB_PROCEDURE1('" + tableName + "'); ");
                        sql.Append(" END; ");
                        DalOper.Sql.ExecDDL(sql.ToString());
                        #endregion

                        #region PTYPUB_TRIGGER3
                        sql.Clear();
                        sql.Append(" DROP TRIGGER IF EXISTS " + tableName + "_PTYPUB_TRIGGER3; ");
                        DalOper.Sql.ExecDDL(sql.ToString());
                        sql.Clear();
                        sql.Append(" CREATE TRIGGER " + tableName + "_PTYPUB_TRIGGER3 ");
                        sql.Append(" AFTER DELETE ON " + tableName + " ");
                        sql.Append(" FOR EACH ROW ");
                        sql.Append(" BEGIN ");
                        sql.Append(" CALL PTYPUB_PROCEDURE1('" + tableName + "'); ");
                        sql.Append(" END; ");
                        DalOper.Sql.ExecDDL(sql.ToString());
                        #endregion
                    }
                    #endregion
                    #endregion

                    uPD.UPDVERSION = DalConst.SqlVer.DATA_TRIGGER_VER;
                    DalOper.Sql.Update(uPD);
                }
                else if (uPD.UPDVERSION > DalConst.SqlVer.DATA_TRIGGER_VER)
                {
                    throw new Exception("程序中的数据库触发器版本(" + DalConst.SqlVer.DATA_TRIGGER_VER + ")低于当前数据库中的版本(" + uPD.UPDVERSION + ")");
                }
                #endregion
            }
        }
        /// <summary>
        /// 更新缓存数据
        /// </summary>
        [BllTrans(LockMode = FunLock.Mode.Local)]
        public partial class ChgCache
        {
            public static void Exec()
            {
                #region 操作执行
                DalOper.Sql.SelectAll<FDWUDT>().ForEach(uDT =>
                {
                    if (BllCache.Base.Infos.ContainsKey(uDT.UDTTABLENAME))
                        BllCache.Base.Infos[uDT.UDTTABLENAME].SqlUpdateTime = (uDT.UDTUPDATEDATE + uDT.UDTUPDATETIME).ToDateTime();
                });
                MethodInfo methodInfo = DalOper.Sql.GetType().GetMethod(nameof(DalSqlBase.SqlOper.SelectAll));
                foreach (var tableInfo in BllCache.Base.Infos.Values)
                    if (tableInfo.SysUpdateTime != tableInfo.SqlUpdateTime)
                    {
                        tableInfo.Data = methodInfo.MakeGenericMethod(tableInfo.Type).Invoke(DalOper.Sql, new object[] { DalSqlBase.Msg.SELECT_EXEC_FAIL });
                        tableInfo.SysUpdateTime = tableInfo.SqlUpdateTime;
                    }
                #endregion
            }
        }
    }
}
